﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using BobcatUtility;
using BobcatMultiTouch;
using CNShapes;
using CNPageViewer;

namespace CNPageEditor
{
    /// <summary>
    /// This is a base class for gesture-handlers. These classes get the 'first-look'
    /// at touch events and try to determine if a defined gesture has been made. If
    /// it has they raise an event. The event can specify a new action which should
    /// replace the current active action used by the shape-editor controol.
    /// </summary><remarks>
    /// 
    /// Reseting gesture handlers
    /// -------------------------
    /// The PageEditorControl detects when one action has completed and it needs to
    /// start the next one. At the same time, it needs to check whether a gesture is 
    /// occuring instead. The classes derived from this base class check for gestures.
    /// 
    /// If a gesture has not occured, the derived class may well "give up" checking for
    /// he gesture. For example, if the 'gesture' is a double-click then we may only 
    /// check for the double-click from the first touch events. If it hasn't happened
    /// then we assume that the gesture wasn't intended, and that a standard action was
    /// taking place instead.
    /// 
    /// When the action has completed and the next one has begun, we want to check for 
    /// the action again. To do this, the editor control calls the onNewAction() method. 
    /// Derived classes should reset their gestures here and check for them again with 
    /// the next set of touch-events they receive.
    /// 
    /// </remarks>
    public abstract class GestureHandler
    {
        #region Events

        /// <summary>
        /// Data passed with events from this class.
        /// </summary>
        public class Args : EventArgs
        {
            public Action NewAction { get; set; } // The action we are requesting be performed.
            public bool RevertToPreviousActionWhenComplete { get; set; } // True if we should go back to the previous action once this action is complete; false to make this action the default action from now on.
        }

        /// <summary>
        /// Event raised when we detect a gesture.
        /// </summary>
        public event EventHandler<Args> GestureDetectedEvent;

        /// <summary>
        /// Derived classes can call this function to raise the gesture-detected event.
        /// </summary>
        protected void raiseGestureDetectedEvent(Args args)
        {
            Utility.raiseEvent(GestureDetectedEvent, this, args);
        }

        #endregion

        #region Public methods

        /// <summary>
        /// Initializes the gesture-handler with useful objects it may need to use
        /// or interact with.
        /// </summary>
        public void initialize(Page page, PageEditorControl pageEditorControl)
        {
            m_Page = page;
            m_PageEditorControl = pageEditorControl;
            m_PageViewerControl = pageEditorControl.PageViewer;

            // We call initialize() in derived classes...
            initialize();
        }

        /// <summary>
        /// Called to initialize the gesture-handler. (Called after the base-class initialize has been called.)
        /// </summary>
        public abstract void initialize();

        /// <summary>
        /// Called to let the gesture know that a new action has started. The gesture may (or may not)
        /// want to reset at this point.
        /// </summary>
        public abstract void onNewAction();

        /// <summary>
        /// Called when a touch-down event occurs.
        /// </summary>
        public abstract void onTouchDown(TouchArgs touchArgs);

        /// <summary>
        /// Called when a touch-move event occurs.
        /// </summary>
        public abstract void onTouchMove(TouchArgs touchArgs);

        /// <summary>
        /// Called when a touch-up event occurs.
        /// </summary>
        public abstract void onTouchUp(TouchArgs touchArgs);

        #endregion

        #region Protected data

        protected Page m_Page = null;
        protected PageEditorControl m_PageEditorControl = null;
        protected PageViewerControl m_PageViewerControl = null;

        #endregion
    }
}
